package classfile

// 表示方法引用的常量池项
type ConstantMethodHandlerInfo struct {
	// 引用类型。它的值必须在0~9以内，表示方法句柄的类型，句柄类型会决定字节码的行为
	refrenceKind  uint8
	// 对常量池的索引，需要符合一下规则
	// 如果refrence_kind 为1(REF_getField)、2(REF_getStatic)、3(REF_putField)或4(REF_putStatic)，
	//     则常量池指定位置必须是FieldRef结构，表示某个字段，本方法句柄正是为这个字段创建的
	// 如果值为5(REF_invokeVirtual)或者8(REF_newInvokeSpecial),
	//     则常量池此位置必须是MethodRef结构，本方法句柄正是为这个方法或构造器创建的
	// 如果值为6(REF_invokeStatic)或7(REF_invokeSpecial)，且class文件版本号小于52.0，则必须为MethodRef结构。
	//     如果大于52.0则还可以是InterfaceMethodRef结构
	// 如果值为9(REF_invokeInterface)，则常量池指定位置上必须是一个InterfaceMethodRef结构，表示接口中某个方法
	// 如果值为5(REF_invokeVirtual)、6(REF_invokeStatic)、7(REF_invokeSpecial)或9(REF_invokeInterface)，
	//     那么MethodREF或者InterfaceMethod结构所表示的方法，其名称不能是<init>或<clinit>
	// 如果值为8(REF_newInvokeSpecial)，那么由MethodRef结构所表示的方法，其名称必须为<init>
	refrenceIndex uint16
}

func (self *ConstantMethodHandlerInfo) readInfo(reader *ClassReader) {
	self.refrenceKind = reader.ReadUint8()
	self.refrenceIndex = reader.ReadUint16()
}

// 表示方法类型的常量池项
type ConstantMethodTypeInfo struct {
	// 对常量池的有效索引，常量池此位置上必须是一个UTF8结构，表示此方法的描述符
	descriptorIndex uint16
}

func (self *ConstantMethodTypeInfo) readInfo(reader *ClassReader) {
	self.descriptorIndex = reader.ReadUint16()
}

// 表示invokeDynamic指令用到的引导方法的常量池项
type ConstantInvokeDynamicInfo struct {
	// 必须是对当前class文件中引导方法表的bootstrap_methods数组的有效索引
	bootStrapMethodAttrIndex uint16
	// 对常量池表的有效索引，常量池此位置上必须是NameAndType结构，表示此引导方法的名称和类型描述
	nameAndTypeIndex         uint16
}

func (self *ConstantInvokeDynamicInfo) readInfo(reader *ClassReader) {
	self.bootStrapMethodAttrIndex = reader.ReadUint16()
	self.nameAndTypeIndex = reader.ReadUint16()
}
